package com.example.pc.videodemo.emq

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import com.example.myapplication.rabbitmq.OnReceivedMsgListener
import com.example.pc.videodemo.MainActivity
import com.example.pc.videodemo.MyApplication
import com.example.pc.videodemo.MyApplication.Companion.getStack
import com.example.pc.videodemo.R
import com.example.pc.videodemo.emq.model.EmqConstant
import com.example.pc.videodemo.emq.model.MqttMassgePostBase
import com.example.pc.videodemo.toast
import com.google.gson.Gson
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.*
import kotlin.concurrent.thread


class MqttMessageService : Service() {
    /**
     * 订阅的主题
     */
    private var mqttAndroidClient: MqttAndroidClient? = null
    private var mqttConnectOptions: MqttConnectOptions? = null
    private var onReceivedMsgListener: OnReceivedMsgListener? = null
    private var equipmentId = ""
    private val TAG="mqtt----"
    private var builder: NotificationCompat.Builder? = null
    fun setOnReceivedMsgListener(onReceivedMsgListener: OnReceivedMsgListener) {
        this.onReceivedMsgListener = onReceivedMsgListener
    }

    /**
     * 连接mqtt
     */
    fun connectMqtt() {
        try {
            mqttAndroidClient?.connect(mqttConnectOptions, null, object : IMqttActionListener {
                override fun onSuccess(asyncActionToken: IMqttToken) {}
                override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                    Log.e(TAG, "onFailure: "+"MQTT连接失败！！！！" + exception?.cause )
                    exception?.printStackTrace()
                    if (exception?.message?.contains("已连接") == true)
                        return
                    Thread {
                        Log.e(TAG, "onFailure: "+"30s后，尝试重新连接" )
                        val stack = getStack()
                        var activity: MainActivity? = null
                        if (stack.size > 0 && stack[0] is MainActivity) {
                            activity = stack[0] as MainActivity?
                        }
                        activity?.connectNet(false,"连接失败！！！！" + "尝试重新连接")
                        try {
                            Thread.sleep((1000 * 10).toLong())
                        } catch (e: InterruptedException) {
                            e.printStackTrace()
                        }
                        connectMqtt()
                    }.start()
                }
            })
        } catch (e: Exception) {
            e.printStackTrace()
            onReceivedMsgListener?.onError()
        }
    }
fun disConnect(){
    try {
        mqttAndroidClient?.unregisterResources()

        thread {
            Thread.sleep(50)
            mqttAndroidClient?.disconnect()
        }
    }catch (e:Exception){

    }

}
    /**
     * mqtt初始化
     *
     * @param equipmentId
     */
    fun initMqtt(equipmentId: String) {
        try {

            this.equipmentId = equipmentId
            //写上自己的url
            val uri = MqttConfig.HOST
            mqttAndroidClient = MqttAndroidClient(
                    MyApplication.context,
                    uri, equipmentId)
            mqttAndroidClient?.setCallback(object : MqttCallbackExtended {
                override fun connectComplete(reconnect: Boolean, serverURI: String) {
                    if (reconnect) {
                        Log.i(TAG, "connectComplete: "+"MQTT重新连接成功！serverURI:$serverURI")
                    } else {
                        Log.i(TAG, "connectComplete: "+"MQTT连接成功！serverURI:$serverURI")
                    }
                    subscribeAllTopics()
                }

                override fun connectionLost(cause: Throwable?) {
                    Log.i(TAG, "connectionLost: "+"MQTT连接断开！" + cause?.cause)
                    val stack = getStack()
                    var activity: MainActivity? = null
                    if (stack.size > 0 && stack[0] is MainActivity) {
                        activity = stack[0] as MainActivity?
                    }
                    activity?.connectNet(false,"连接断开！")
                }

                override fun messageArrived(topic: String, message: MqttMessage) {
                    Log.i(TAG, "messageArrived: "+"收到了消息：" + topic + message.toString() + message.getQos())
                    onReceivedMsgListener?.onReceived(message.toString())
                }

                override fun deliveryComplete(token: IMqttDeliveryToken) {
                    try {
                        val mqttMessage: MqttMessage = token.getMessage()
                        Log.i(TAG, "deliveryComplete: "+"消息发送成功:" + mqttMessage.toString())
//                        if (mqttMessage.toString().contains("offLine")){
//                            disConnect()
//                        }
                    } catch (e: MqttException) {
                        e.printStackTrace()
                    }
                }
            })

            // 新建连接设置
            mqttConnectOptions = MqttConnectOptions()
            mqttConnectOptions?.setUserName(MqttConfig.EMQ_USERNAME)
            mqttConnectOptions?.setPassword(MqttConfig.EMQ_PASSWORD.toCharArray())
            //断开后，是否自动连接
            mqttConnectOptions?.setAutomaticReconnect(true)
            //是否清空客户端的连接记录。若为true，则断开后，broker将自动清除该客户端连接信息
            mqttConnectOptions?.setCleanSession(true)
            //设置超时时间，单位为秒
            mqttConnectOptions?.setConnectionTimeout(15)
            //心跳时间，单位为秒。即多长时间确认一次Client端是否在线
            mqttConnectOptions?.setKeepAliveInterval(10)
            //允许同时发送几条消息（未收到broker确认信息）
            mqttConnectOptions?.setMaxInflight(30)
            val offLine = MqttMassgePostBase()
            offLine.code = EmqConstant.androidToServerEnum.offlie.code
            offLine.sn = equipmentId
            val gson = Gson()
            mqttConnectOptions?.setWill(MqttConfig.WILLTOPIC,gson.toJson(offLine).toByteArray(),1,false)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 订阅所有主题
     */
    private fun subscribeAllTopics() {
        //订阅主消息主题和更新消息主题
        subscribeToTopic(MqttConfig.TOPIC + equipmentId, 1)
    }

    /**
     * 订阅一个主主题
     *
     * @param subTopic 主题名称
     */
    private fun subscribeToTopic(subTopic: String, qos: Int) {
        try {
            mqttAndroidClient?.subscribe(subTopic, qos, null, object : IMqttActionListener {
                override fun onSuccess(asyncActionToken: IMqttToken) {
                    Log.i(TAG, "onSuccess: MQTT订阅消息成功：$subTopic")
                    onReceivedMsgListener?.onConnect()
                }

                override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                    Log.i(TAG, "onFailure: MQTT订阅消息失败！$subTopic")
                    Thread {
                        Log.e(TAG, "onFailure: "+"30s后，尝试重新连接" )
                        val stack = getStack()
                        var activity: MainActivity? = null
                        if (stack.size > 0 && stack[0] is MainActivity) {
                            activity = stack[0] as MainActivity?
                        }
                        activity?.connectNet(false,"连接失败！！！！" + "尝试重新连接")
                        try {
                            Thread.sleep((1000 * 10).toLong())
                        } catch (e: InterruptedException) {
                            e.printStackTrace()
                        }
                        subscribeToTopic(subTopic, qos)
                    }.start()
                }
            })
        } catch (ex: Exception) {
            Log.i(TAG, "subscribeToTopic: "+"subscribeToTopic: Exception whilst subscribing")
            ex.printStackTrace()
            onReceivedMsgListener?.onError()
        }
    }

    /**
     * 发布主题
     *
     * @param msg 内容
     * @param qos qos
     */
    @JvmOverloads
    fun publishMessage(msg: String, qos: Int = 1) {
        if (mqttAndroidClient != null && mqttAndroidClient?.isConnected() == true) {
            try {
                Log.i(TAG, "publishMessage: "+"publishMessage: 发送$msg")
                mqttAndroidClient?.publish(MqttConfig.PUBLICTOPIC, msg.toByteArray(), qos, false)
            } catch (e: Exception) {
                Log.e(TAG, "publishMessage: "+"publishMessage: Error Publishing: " + e.message)
                e.printStackTrace()
            }
        } else {
            Log.e(TAG, "publishMessage: "+"publishMessage失败，MQTT未连接 ")
        }
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        return START_NOT_STICKY
    }

    override fun onDestroy() {

        Log.e(TAG, "onDestroy: "+"关闭MQTT")
        //断开mqtt连接
        try {
            if (mqttAndroidClient != null && mqttAndroidClient?.isConnected() == true) {
                mqttAndroidClient?.disconnect()
                mqttAndroidClient?.unregisterResources()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        super.onDestroy()
    }

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

}